﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;

public class CreateCubMesh : MonoBehaviour {



    [SerializeField]
    public GameObject CubPrefab;

    //void updateMesh()
    //{
    //    MeshFilter mf = this.gameObject.GetComponent<MeshFilter>();
    //    if(isModify)
    //    {
    //        editMesh.CombineMeshes(meshCombines.ToArray(), false);
    //        mf.mesh = editMesh;
    //    }
    //}

    public void Init()
    {

        //if(editMesh == null)
        //{
        editMesh = new Mesh();
        //}

        if(meshCombines == null)
        {
            meshCombines = new List<CombineInstance>();
        }

        if (subMeshObjs == null)
        {
            subMeshObjs = new Dictionary<int, GameObject>();
        }

    }

    public void Reset()
    {
        editMesh = null;
        meshCombines = null;
    }

    //清理当前编辑的Mesh
    public void Clear()
    {
        editMesh.Clear();
        meshCombines.Clear();

        foreach (KeyValuePair<int, GameObject> kvp in subMeshObjs)
        {
            DestroyImmediate(kvp.Value);
        }
        subMeshObjs.Clear();

    }

    //编辑用Mesh
    Mesh editMesh = null; 
    //存放subMesh
    List<CombineInstance> meshCombines = null;
    Dictionary<int,GameObject> subMeshObjs = null;

    //获取编辑后的Mesh数据
    public Mesh GetRootMesh()
    {

        editMesh.Clear();
        meshCombines.Clear();

        foreach (KeyValuePair<int, GameObject> kvp in subMeshObjs)
        {
            CombineInstance newComb = new CombineInstance();
            newComb.mesh = kvp.Value.GetComponent<MeshFilter>().sharedMesh;
            newComb.transform = kvp.Value.transform.localToWorldMatrix;
            meshCombines.Add(newComb);
 
        }

        editMesh.CombineMeshes(meshCombines.ToArray(),true);
        
        return editMesh;

    }


    public void CreateAWrapCube(int _index,float _width, float _length, float _height, float _widUVScale = 1, float _lenUVScale = 1, float _heiUVScale = 1)
    {

        Mesh tempMesh = CreateCubeMesh(_width, _length, _height, _widUVScale, _lenUVScale, _heiUVScale);

        //创建一个新Obj用于编辑
        //GameObject cubeObj = new GameObject("subcube" + (_index));
        GameObject cubePrefab = AssetDatabase.LoadAssetAtPath("Assets/CustomMeshSample/Cube.prefab", typeof(GameObject)) as GameObject;

        GameObject cubeObj = GameObject.Instantiate(cubePrefab);
        cubeObj.name = "Cube_" + _index;
        cubeObj.transform.SetParent(this.gameObject.transform);
        cubeObj.transform.localScale = Vector3.one;
        cubeObj.transform.position = Vector3.zero;
        cubeObj.GetComponent<MeshFilter>().mesh = tempMesh;
        //MeshRenderer mr = cubeObj.AddComponent<MeshRenderer>();
        //MeshFilter mf = cubeObj.AddComponent<MeshFilter>();

        //让纹理可以平铺
        cubeObj.GetComponent<Renderer>().sharedMaterial.mainTexture.wrapMode = TextureWrapMode.Repeat;

        subMeshObjs[_index] = cubeObj;

    }


    //    7  -------- 5
    //     /|       /|
    //    / |      / |
    // 1 --------- 3 |
    //   | 6/ ----|- /4
    //   | /      | / 
    //   |        |/
    // 0 ---------  2
    public Mesh CreateCubeMesh(float _width, float _length, float _height, float _widUVScale = 1, float _lenUVScale = 1, float _heiUVScale = 1)
    {
        const int vecCount = 24;
        Vector3[] vecs = new Vector3[vecCount];

        float xpos = _width / 2;
        float ypos = _height / 2;
        float zpos = _length / 2;


        //front
        vecs[0] = new Vector3(-xpos, -ypos, -zpos);
        vecs[1] = new Vector3(-xpos, ypos, -zpos);
        vecs[2] = new Vector3(xpos, -ypos, -zpos);
        vecs[3] = new Vector3(xpos, ypos, -zpos);
        //back
        vecs[4] = new Vector3(xpos, -ypos, zpos);
        vecs[5] = new Vector3(xpos, ypos, zpos);
        vecs[6] = new Vector3(-xpos, -ypos, zpos);
        vecs[7] = new Vector3(-xpos, ypos, zpos);

        //每个面都要绘制4个顶点,因为顶点不仅仅存放了位置信息还有法线uv信息，一个顶点三个面公用其法线和uv信息不相同。
        //right
        vecs[8] = vecs[2];
        vecs[9] = vecs[3];
        vecs[10] = vecs[4];
        vecs[11] = vecs[5];

        //left
        vecs[12] = vecs[6];
        vecs[13] = vecs[7];
        vecs[14] = vecs[0];
        vecs[15] = vecs[1];

        //top
        vecs[16] = vecs[1];
        vecs[17] = vecs[7];
        vecs[18] = vecs[3];
        vecs[19] = vecs[5];

        //down
        vecs[20] = vecs[6];
        vecs[21] = vecs[0];
        vecs[22] = vecs[4];
        vecs[23] = vecs[2];

        //uv坐标
        Vector2[] uvs = new Vector2[vecCount];


        float maxupos = 1 * _widUVScale;
        float maxvpos = 1 * _heiUVScale;
        float maxlvpos = 1 * _lenUVScale;


        for (int i = 0; i < vecCount;)
        {

            //uvs[i++] = new Vector2(0, maxvpos);
            //uvs[i++] = new Vector2(0, 0);
            //uvs[i++] = new Vector2(maxupos, maxvpos);
            //uvs[i++] = new Vector2(maxupos, 0);

            if (i < 8)//前后UV一致
            {
                uvs[i++] = new Vector2(0, maxvpos);
                uvs[i++] = new Vector2(0, 0);
                uvs[i++] = new Vector2(maxupos, maxvpos);
                uvs[i++] = new Vector2(maxupos, 0);
            }
            else if (i >= 8 && i < 16)//左右一致
            {
                uvs[i++] = new Vector2(0, maxvpos);
                uvs[i++] = new Vector2(0, 0);
                uvs[i++] = new Vector2(maxlvpos, maxvpos);
                uvs[i++] = new Vector2(maxlvpos, 0);
            }
            else//上下一致
            {
                uvs[i++] = new Vector2(0, maxlvpos);
                uvs[i++] = new Vector2(0, 0);
                uvs[i++] = new Vector2(maxupos, maxlvpos);
                uvs[i++] = new Vector2(maxupos, 0);
            }

        }


        //                  
        //                b  \________\ c
        //                  /         /
        //                 /         /
        //               \/_________/
        //               a                    
        //法线的这个方向向量是基于顶点坐标系
        //顶点坐标系的正方向取决于顶点所在平面的朝向
        //顶点所在平面的朝向由构成这个平面顶点间向量的X乘来决定（ab-> x bc-> ）（顺时针法则，左手沿顶点顺时针旋转向外的方向）
        Vector3[] normals = new Vector3[vecCount];
        for (int i = 0; i < vecCount; i++)
        {
            normals[i] = Vector3.up;

        }


        int[] indices = new int[36];

        //front
        indices[0] = 0;
        indices[1] = 1;
        indices[2] = 2;
        indices[3] = 2;
        indices[4] = 1;
        indices[5] = 3;

        //right
        indices[6] = 8;
        indices[7] = 9;
        indices[8] = 10;
        indices[9] = 10;
        indices[10] = 9;
        indices[11] = 11;

        //back
        indices[12] = 4;
        indices[13] = 5;
        indices[14] = 6;
        indices[15] = 6;
        indices[16] = 5;
        indices[17] = 7;

        //left
        indices[18] = 12;
        indices[19] = 13;
        indices[20] = 14;
        indices[21] = 14;
        indices[22] = 13;
        indices[23] = 15;

        //top
        indices[24] = 16;
        indices[25] = 17;
        indices[26] = 18;
        indices[27] = 18;
        indices[28] = 17;
        indices[29] = 19;

        //down
        indices[30] = 20;
        indices[31] = 21;
        indices[32] = 22;
        indices[33] = 22;
        indices[34] = 21;
        indices[35] = 23;

        Mesh mesh = new Mesh();
        mesh.vertices = vecs;
        mesh.uv = uvs;
        mesh.triangles = indices;
        mesh.normals = normals;

        return mesh;

    }
}
